昨天我們介紹fetch用get方式來請求資料,並將取得的資料轉為JSON格式做運用,今天要來介紹fetch的post方法,用非同步的方式來傳送表單資料。以下開始進入主題:
沿用前天彈出表單視窗的範例,為了可以讓程式碼變得更簡短,這裡僅保留表單直接放入render,並去除彈跳視窗功能模組(Modal):
src/pages/Contact.js
//引入外框組件
import { App } from './App'
export const Contact = {
render: () => {
const content = `
<div class="container">
<h1>填寫表單</h1>
<h6>請填寫下方表單</h6>
<form>
<div class="form-group">
<label for="name">稱呼</label>
<input type="text" class="form-control" name="name" placeholder="請填寫您的稱呼" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="email" placeholder="請填寫email" required>
</div>
<div class="form-group">
<label for="message">留言內容</label>
<textarea type="email" class="form-control" name="message" placeholder="請填寫內容" required></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" id="submit">提交</button>
</div>
</form>
</div>
`
return App.render(content)
},
}
表單裡我們放置三個輸入框,依序是name、email及message,為了等等傳送表單資料(formData),將每個輸入框給予name屬性,最後再放置一個送出的submit button。
我們先看看下面的例子,這是所熟知最傳統的方式,使用html的form來傳送,要傳送表單資料除了設定method為POST,enctype也要設定為multipart/form-data。
<form action="https://test.com/post" method="POST" enctype="multipart/form-data">
不過這樣的方式會造成請求資源的同時做轉址,轉向至action設定的 「https://test.com/post」 ,為了不讓瀏覽器產生轉址,我們可以使用javascript建立表單物件,搭配使用非同步的方式來傳送資料。直接來看fetch POST如何運行:
src/pages/Contact.js
export const Contact = {
listener: {
click: function (e) {
if (
e.target.closest('button') &&
e.target.closest('button').id === 'submit'
) {
//取消預設submit事件
e.preventDefault()
// 建立formData物件
const fd = new FormData(document.querySelector('form'))
// fetch post
fetch('test.com/post', {
method: 'POST',
body: fd,
headers: { 'Content-Type': 'multipart/form-data' },
})
.then((res) => res.json())
.then((data) => {
console.log(data)
})
}
},
},
render: () => {
這邊新增listener屬性來增加click監聽事件,需要注意的是當按下submit按鈕時,要用preventDefault()取消預設submit事件,否則會轉址。建立表單物件起手式,宣告並建立FormData表單物件,可以帶入現有的表單做傳送,或是建立後使用append來增加表單資料,參閱MDN上面的說明:
FormData 介面可為表單資料中的欄位/值建立相對應的的鍵/值對(key/value)集合,之後便可使用 XMLHttpRequest.send() 方法來送出資料。它在編碼類型設定為 multipart/form-data 時會採用與表單相同的格式送出。
在fetch的第一個參數放入URI,因為手邊沒有API,所以先隨意打,這邊只要了解body夾帶的資料內容。比較重要的是第二個參數設定如下:
{
method: 'POST',
body: fd,
headers: { 'Content-Type': 'multipart/form-data' },
}
填完資料後按下送出,用Chrome Devtools到Network看看body傳送的資訊:
可以看到框框處是formData裡面傳送的資料,其中key對應form表單的name,value對應為填入表單的值。以上就是使用fetch post來傳輸資料,以上實做到這裡算是結束了,準備迎接完賽日的到來吧:)